
/* verilator lint_off UNDRIVEN */
/* verilator lint_off UNUSED */
`include "defines.v"
// `include "ff.v"

module MemAccCtrl(
    input wire clk,
    input wire rst,

    // with cpu
    input wire                  r_if_ena,
    input wire [`REG_BUS-1 : 0] r_if_addr,
    input wire [         2 : 0] r_if_bytes,

    input wire                  r_mem_ena,
    input wire                  w_mem_ena,
    input wire [`REG_BUS-1 : 0] rw_mem_addr,
    input wire [         2 : 0] rw_mem_bytes,
    input wire [`REG_BUS-1 : 0] w_mem_data,

    output wire                 ready,
    output wire [`INS_BUS-1 : 0] if_data,
    output wire [`REG_BUS-1 : 0] mem_data,

    //with AXI4

    input  [`REG_BUS-1 : 0] r_data_from_axi4,
    input                   r_ready_from_axi4,
    input                   w_ready_from_axi4,
    output r_ena_to_axi4,
    output w_ena_to_axi4,
    output [`REG_BUS-1 : 0] addr_to_axi4,
    output [`REG_BUS-1 : 0] w_data_to_axi4,
    output [         7 : 0] w_mask_to_axi4
);

    // State register
    reg [2:0] state, nxt_state;

    always @(posedge clk) begin
        if(rst) state <= 3'd0;
        else state <= nxt_state;
    end

    always@(*) case(state)
        3'd0: begin
            if(r_mem_ena) nxt_state = 3'd3;
            else if(w_mem_ena) nxt_state = 3'd5;
            else if(r_if_ena) nxt_state = 3'd1;
            else nxt_state = 3'd0;
        end
        3'd1: begin
            if(r_ready_from_axi4 & (~misalign_IF)) nxt_state = 3'd0;
            else if(r_ready_from_axi4 & misalign_IF) nxt_state = 3'd2;
            else nxt_state = 3'd1;
        end
        3'd2: begin
            if(r_ready_from_axi4) nxt_state = 3'd0;
            else nxt_state = 3'd2;
        end
        3'd3: begin
            if(r_ready_from_axi4 & (~misalign_MEM)) nxt_state = 3'd1;
            else if(r_ready_from_axi4 & misalign_MEM) nxt_state = 3'd4;
            else nxt_state = 3'd3;
        end
        3'd4: begin
            if(r_ready_from_axi4) nxt_state = 3'd1;
            else nxt_state = 3'd4;
        end
        3'd5: begin
            if(w_ready_from_axi4 & (~misalign_MEM)) nxt_state = 3'd1;
            else if(w_ready_from_axi4 & misalign_MEM) nxt_state = 3'd6;
            else nxt_state = 3'd5;
        end
        3'd6: begin
            if(w_ready_from_axi4) nxt_state = 3'd1;
            else nxt_state = 3'd6;
        end
        default: nxt_state = 3'd0;
    endcase

    // output <> cpu
    reg ready_reg;
    reg [`INS_BUS-1 : 0] if_data_reg;
    reg [`REG_BUS-1 : 0] mem_data_reg;

    assign ready = ready_reg;
    assign if_data = if_data_reg;
    assign mem_data = mem_data_reg;

    always@(posedge clk) begin
        if(rst) ready_reg <= 1'b0;
        else ready_reg <= (nxt_state == 3'd0);
    end

    always @(posedge clk) begin
        if(rst) if_data_reg <= `INS_BUS'd0;
        else begin
            if(state==3'd1 && r_ready_from_axi4)begin
                case(r_if_addr[2:0]) 
                    3'b000: if_data_reg <= r_data_from_axi4[4*8-1:0*8];
                    3'b001: if_data_reg <= r_data_from_axi4[5*8-1:1*8];
                    3'b010: if_data_reg <= r_data_from_axi4[6*8-1:2*8];
                    3'b011: if_data_reg <= r_data_from_axi4[7*8-1:3*8];
                    3'b100: if_data_reg <= r_data_from_axi4[8*8-1:4*8];
                    3'b101: if_data_reg <= {8'b0, r_data_from_axi4[8*8-1:5*8]};
                    3'b110: if_data_reg <= {16'b0, r_data_from_axi4[8*8-1:6*8]};
                    3'b111: if_data_reg <= {24'b0, r_data_from_axi4[8*8-1:7*8]};
                endcase
            end
            else if(state==3'b2 && r_ready_from_axi4)begin
                case(r_if_addr[2:0])
                    3'b000: if_data_reg <= if_data_reg;
                    3'b001: if_data_reg <= if_data_reg;
                    3'b010: if_data_reg <= if_data_reg;
                    3'b011: if_data_reg <= if_data_reg;
                    3'b100: if_data_reg <= if_data_reg;
                    3'b101: if_data_reg <= {r_data_from_axi4[1*8-1:0], if_data_reg[3*8-1:0*8]};
                    3'b110: if_data_reg <= {r_data_from_axi4[2*8-1:0], if_data_reg[2*8-1:0*8]};
                    3'b111: if_data_reg <= {r_data_from_axi4[3*8-1:0], if_data_reg[1*8-1:0*8]};
                endcase
            end
            else if_data_reg <= if_data_reg;
        end
    end

    always @(posedge clk) begin
        if(rst) mem_data_reg <= `REG_BUS'd0;
        else begin
            if(state==3'd3 && r_ready_from_axi4)begin
                case(rw_mem_bytes[1:0])
                    2'b00: case(rw_mem_addr[2:0])
                        3'b000: mem_data_reg <= {{56{r_data_from_axi4[1*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[1*8-1:0*8]};
                        3'b001: mem_data_reg <= {{56{r_data_from_axi4[2*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[2*8-1:1*8]};
                        3'b010: mem_data_reg <= {{56{r_data_from_axi4[3*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[3*8-1:2*8]};
                        3'b011: mem_data_reg <= {{56{r_data_from_axi4[4*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[4*8-1:3*8]};
                        3'b100: mem_data_reg <= {{56{r_data_from_axi4[5*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[5*8-1:4*8]};
                        3'b101: mem_data_reg <= {{56{r_data_from_axi4[6*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[6*8-1:5*8]};
                        3'b110: mem_data_reg <= {{56{r_data_from_axi4[7*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[7*8-1:6*8]};
                        3'b111: mem_data_reg <= {{56{r_data_from_axi4[8*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[8*8-1:7*8]};
                    endcase
                    2'b01: case(rw_mem_addr[2:0])
                        3'b000: mem_data_reg <= {{48{r_data_from_axi4[2*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[2*8-1:0*8]};
                        3'b001: mem_data_reg <= {{48{r_data_from_axi4[3*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[3*8-1:1*8]};
                        3'b010: mem_data_reg <= {{48{r_data_from_axi4[4*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[4*8-1:2*8]};
                        3'b011: mem_data_reg <= {{48{r_data_from_axi4[5*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[5*8-1:3*8]};
                        3'b100: mem_data_reg <= {{48{r_data_from_axi4[6*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[6*8-1:4*8]};
                        3'b101: mem_data_reg <= {{48{r_data_from_axi4[7*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[7*8-1:5*8]};
                        3'b110: mem_data_reg <= {{48{r_data_from_axi4[8*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[8*8-1:6*8]};
                        3'b111: mem_data_reg <= {{56{r_data_from_axi4[8*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[8*8-1:7*8]};
                    endcase
                    2'b10: case(rw_mem_addr[2:0])
                        3'b000: mem_data_reg <= {{32{r_data_from_axi4[4*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[4*8-1:0*8]};
                        3'b001: mem_data_reg <= {{32{r_data_from_axi4[5*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[5*8-1:1*8]};
                        3'b010: mem_data_reg <= {{32{r_data_from_axi4[6*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[6*8-1:2*8]};
                        3'b011: mem_data_reg <= {{32{r_data_from_axi4[7*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[7*8-1:3*8]};
                        3'b100: mem_data_reg <= {{32{r_data_from_axi4[8*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[8*8-1:4*8]};
                        3'b101: mem_data_reg <= {{40{r_data_from_axi4[8*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[8*8-1:5*8]};
                        3'b110: mem_data_reg <= {{48{r_data_from_axi4[8*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[8*8-1:6*8]};
                        3'b111: mem_data_reg <= {{56{r_data_from_axi4[8*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[8*8-1:7*8]};
                    endcase
                    2'b11: case(rw_mem_addr[2:0])
                        3'b000: mem_data_reg <= r_data_from_axi4[8*8-1:0*8];
                        3'b001: mem_data_reg <= {{ 8{r_data_from_axi4[8*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[8*8-1:1*8]};
                        3'b010: mem_data_reg <= {{16{r_data_from_axi4[8*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[8*8-1:2*8]};
                        3'b011: mem_data_reg <= {{24{r_data_from_axi4[8*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[8*8-1:3*8]};
                        3'b100: mem_data_reg <= {{32{r_data_from_axi4[8*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[8*8-1:4*8]};
                        3'b101: mem_data_reg <= {{40{r_data_from_axi4[8*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[8*8-1:5*8]};
                        3'b110: mem_data_reg <= {{48{r_data_from_axi4[8*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[8*8-1:6*8]};
                        3'b111: mem_data_reg <= {{56{r_data_from_axi4[8*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[8*8-1:7*8]};
                    endcase
                endcase
            end  
            else if(state==3'd4 && r_ready_from_axi4) begin
                case(rw_mem_bytes[1:0])
                    2'b00: mem_data_reg <= mem_data_reg;
                    2'b01: case(rw_mem_addr[2:0])
                        3'b111: mem_data_reg <= {{48{r_data_from_axi4[1*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[1*8-1:0*8], mem_data_reg[1*8-1:0*8]};
                        default: mem_data_reg <= mem_data_reg;
                    endcase
                    2'b10: case(rw_mem_addr[2:0])
                        3'b101: mem_data_reg <= {{32{r_data_from_axi4[1*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[1*8-1:0*8], mem_data_reg[3*8-1:0*8]};
                        3'b110: mem_data_reg <= {{32{r_data_from_axi4[2*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[2*8-1:0*8], mem_data_reg[2*8-1:0*8]};
                        3'b111: mem_data_reg <= {{32{r_data_from_axi4[3*8-1]&(~rw_mem_bytes[2])}}, r_data_from_axi4[3*8-1:0*8], mem_data_reg[1*8-1:0*8]};
                        default: mem_data_reg <= mem_data_reg;
                    endcase
                    2'b11: case(rw_mem_addr[2:0])
                        3'b001: mem_data_reg <= {r_data_from_axi4[1*8-1:0*8], mem_data_reg[7*8-1:0*8]};
                        3'b010: mem_data_reg <= {r_data_from_axi4[2*8-1:0*8], mem_data_reg[6*8-1:0*8]};
                        3'b011: mem_data_reg <= {r_data_from_axi4[3*8-1:0*8], mem_data_reg[5*8-1:0*8]};
                        3'b100: mem_data_reg <= {r_data_from_axi4[4*8-1:0*8], mem_data_reg[4*8-1:0*8]};
                        3'b101: mem_data_reg <= {r_data_from_axi4[5*8-1:0*8], mem_data_reg[3*8-1:0*8]};
                        3'b110: mem_data_reg <= {r_data_from_axi4[6*8-1:0*8], mem_data_reg[2*8-1:0*8]};
                        3'b111: mem_data_reg <= {r_data_from_axi4[7*8-1:0*8], mem_data_reg[1*8-1:0*8]};
                        default: mem_data_reg <= mem_data_reg;
                    endcase
                endcase
            end
            else mem_data_reg <= mem_data_reg;
        end
    end



    // is misaligned IF
    wire [3:0] remain_bytes_IF;
    wire [3:0] need_bytes_IF;
    wire misalign_IF;
    wire [4:0] additional_bytes_IF;

    assign need_bytes_IF = {r_if_bytes[1]&r_if_bytes[0], r_if_bytes[1]&(~r_if_bytes[0]), (~r_if_bytes[1])&r_if_bytes[0], (~r_if_bytes[1])&(~r_if_bytes[0])};
    assign remain_bytes_IF = 4'b1000 - {1'b0, r_if_addr[2:0]};
    assign additional_bytes_IF = {1'b0, need_bytes_IF} - {1'b0, remain_bytes_IF};
    assign misalign_IF = ~((additional_bytes_IF[4]) | (additional_bytes_IF==5'b0));


    // is misaligned MEM
    wire [3:0] remain_bytes_MEM;
    wire [3:0] need_bytes_MEM;
    wire misalign_MEM;
    wire [4:0] additional_bytes_MEM;

    assign need_bytes_MEM = {rw_mem_bytes[1]&rw_mem_bytes[0], rw_mem_bytes[1]&(~rw_mem_bytes[0]), (~rw_mem_bytes[1])&rw_mem_bytes[0], (~rw_mem_bytes[1])&(~rw_mem_bytes[0])};
    assign remain_bytes_MEM = 4'b1000 - {1'b0, rw_mem_addr[2:0]};
    assign additional_bytes_MEM = {1'b0, need_bytes_MEM} - {1'b0, remain_bytes_MEM};
    assign misalign_MEM = ~((additional_bytes_MEM[4]) | (additional_bytes_MEM==5'b0));



    //Output <> AXI4
    reg r_ena_to_axi4_reg;
    reg w_ena_to_axi4_reg;
    reg [`REG_BUS-1 : 0] addr_to_axi4_reg;
    reg [`REG_BUS-1 : 0] w_data_to_axi4_reg;
    reg [         7 : 0] w_mask_to_axi4_reg;

    always @(posedge clk) begin
        if(rst) r_ena_to_axi4_reg <= 1'b0;
        else r_ena_to_axi4_reg <= (nxt_state==3'd1 | nxt_state==3'd2 | nxt_state==3'd3 | nxt_state==3'd4); 
    end

    always @(posedge clk) begin
        if(rst) w_ena_to_axi4_reg <= 1'b0;
        else w_ena_to_axi4_reg <= (nxt_state==3'd5 | nxt_state==3'd6);
    end

    always @(posedge clk) begin
        if(rst) addr_to_axi4 <= `REG_BUS'd0;
        else begin
            case(nxt_state)
                3'd1: addr_to_axi4 <= r_if_addr;
                3'd2: addr_to_axi4 <= r_if_addr + 64'b1;
                3'd3, 3'd5: addr_to_axi4 <= rw_mem_addr;
                3'd4, 3'd6: addr_to_axi4 <= rw_mem_addr + 64'b1;
                default: addr_to_axi4 <= addr_to_axi4;
            endcase
        end
    end

    always @(posedge clk) begin
        if(rst) w_data_to_axi4_reg <= `REG_BUS'd0;
        else if(nxt_state==3'd5) begin
            case(rw_mem_bytes[1:0])
                2'b00: case(rw_mem_addr[2:0])
                    3'b000: w_data_to_axi4_reg <= {56'b0, w_mem_data[1*8-1:0*8]};
                    3'b001: w_data_to_axi4_reg <= {48'b0, w_mem_data[1*8-1:0*8],  8'b0};
                    3'b010: w_data_to_axi4_reg <= {40'b0, w_mem_data[1*8-1:0*8], 16'b0};
                    3'b011: w_data_to_axi4_reg <= {32'b0, w_mem_data[1*8-1:0*8], 24'b0};
                    3'b100: w_data_to_axi4_reg <= {24'b0, w_mem_data[1*8-1:0*8], 32'b0};
                    3'b101: w_data_to_axi4_reg <= {16'b0, w_mem_data[1*8-1:0*8], 40'b0};
                    3'b110: w_data_to_axi4_reg <= { 8'b0, w_mem_data[1*8-1:0*8], 48'b0};
                    3'b111: w_data_to_axi4_reg <= {       w_mem_data[1*8-1:0*8], 56'b0};
                endcase
                2'b01: case (rw_mem_addr[2:0])
                    3'b000: w_data_to_axi4_reg <= {48'b0, w_mem_data[2*8-1:0*8]};
                    3'b001: w_data_to_axi4_reg <= {40'b0, w_mem_data[2*8-1:0*8],  8'b0};
                    3'b010: w_data_to_axi4_reg <= {32'b0, w_mem_data[2*8-1:0*8], 16'b0};
                    3'b011: w_data_to_axi4_reg <= {24'b0, w_mem_data[2*8-1:0*8], 24'b0};
                    3'b100: w_data_to_axi4_reg <= {16'b0, w_mem_data[2*8-1:0*8], 32'b0};
                    3'b101: w_data_to_axi4_reg <= { 8'b0, w_mem_data[2*8-1:0*8], 40'b0};
                    3'b110: w_data_to_axi4_reg <= {       w_mem_data[2*8-1:0*8], 48'b0};
                    3'b111: w_data_to_axi4_reg <= {       w_mem_data[1*8-1:0*8], 56'b0};
                endcase
                2'b10: case (rw_mem_addr[2:0])
                    3'b000: w_data_to_axi4_reg <= {32'b0, w_mem_data[4*8-1:0*8]};
                    3'b001: w_data_to_axi4_reg <= {24'b0, w_mem_data[4*8-1:0*8],  8'b0};
                    3'b010: w_data_to_axi4_reg <= {16'b0, w_mem_data[4*8-1:0*8], 16'b0};
                    3'b011: w_data_to_axi4_reg <= { 8'b0, w_mem_data[4*8-1:0*8], 24'b0};
                    3'b100: w_data_to_axi4_reg <= {       w_mem_data[4*8-1:0*8], 32'b0};
                    3'b101: w_data_to_axi4_reg <= {       w_mem_data[3*8-1:0*8], 40'b0};
                    3'b110: w_data_to_axi4_reg <= {       w_mem_data[2*8-1:0*8], 48'b0};
                    3'b111: w_data_to_axi4_reg <= {       w_mem_data[1*8-1:0*8], 56'b0};
                endcase
                2'b11: case (rw_mem_addr[2:0])
                    3'b000: w_data_to_axi4_reg <= {w_mem_data[8*8-1:0*8]};
                    3'b001: w_data_to_axi4_reg <= {w_mem_data[7*8-1:0*8],  8'b0};
                    3'b010: w_data_to_axi4_reg <= {w_mem_data[6*8-1:0*8], 16'b0};
                    3'b011: w_data_to_axi4_reg <= {w_mem_data[5*8-1:0*8], 24'b0};
                    3'b100: w_data_to_axi4_reg <= {w_mem_data[4*8-1:0*8], 32'b0};
                    3'b101: w_data_to_axi4_reg <= {w_mem_data[3*8-1:0*8], 40'b0};
                    3'b110: w_data_to_axi4_reg <= {w_mem_data[2*8-1:0*8], 48'b0};
                    3'b111: w_data_to_axi4_reg <= {w_mem_data[1*8-1:0*8], 56'b0};
                endcase
            endcase
        end
        else if(nxt_state==3'd6) begin
            case(rw_mem_bytes[1:0])
                2'b00: w_data_to_axi4_reg <= w_data_to_axi4_reg;
                2'b01: case (rw_mem_addr[2:0])
                    3'b111: w_data_to_axi4_reg <= {65'b0, w_mem_data[2*8-1:1*8]};
                    default: w_data_to_axi4_reg <= w_data_to_axi4_reg;
                endcase
                2'b10: case (rw_mem_addr[2:0])
                    3'b101: w_data_to_axi4_reg <= {56'b0, w_mem_data[4*8-1:3*8]};
                    3'b110: w_data_to_axi4_reg <= {48'b0, w_mem_data[4*8-1:2*8]};
                    3'b111: w_data_to_axi4_reg <= {40'b0, w_mem_data[4*8-1:1*8]};
                    default: w_data_to_axi4_reg <= w_data_to_axi4_reg;
                endcase
                2'b11: case (rw_mem_addr[2:0])
                    3'b000: w_data_to_axi4_reg <= w_data_to_axi4_reg;
                    3'b001: w_data_to_axi4_reg <= {56'b0, w_mem_data[8*8-1:7*8]};
                    3'b010: w_data_to_axi4_reg <= {48'b0, w_mem_data[8*8-1:6*8]};
                    3'b011: w_data_to_axi4_reg <= {40'b0, w_mem_data[8*8-1:5*8]};
                    3'b100: w_data_to_axi4_reg <= {32'b0, w_mem_data[8*8-1:4*8]};
                    3'b101: w_data_to_axi4_reg <= {24'b0, w_mem_data[8*8-1:3*8]};
                    3'b110: w_data_to_axi4_reg <= {16'b0, w_mem_data[8*8-1:2*8]};
                    3'b111: w_data_to_axi4_reg <= { 8'b0, w_mem_data[8*8-1:1*8]};
                endcase
            endcase
        end
    end


    always @(posedge clk) begin
        if(rst) w_mask_to_axi4_reg <= 8'd0;
        else if(nxt_state==3'd5) begin
            case(rw_mem_bytes[1:0])
                2'b00: case(rw_mem_addr[2:0])
                    3'b000: w_mask_to_axi4_reg <= 8'b0000_0001;
                    3'b001: w_mask_to_axi4_reg <= 8'b0000_0010;
                    3'b010: w_mask_to_axi4_reg <= 8'b0000_0100;
                    3'b011: w_mask_to_axi4_reg <= 8'b0000_1000;
                    3'b100: w_mask_to_axi4_reg <= 8'b0001_0000;
                    3'b101: w_mask_to_axi4_reg <= 8'b0010_0000;
                    3'b110: w_mask_to_axi4_reg <= 8'b0100_0000;
                    3'b111: w_mask_to_axi4_reg <= 8'b1000_0000;
                endcase
                2'b01: case (rw_mem_addr[2:0])
                    3'b000: w_mask_to_axi4_reg <= 8'b0000_0011;
                    3'b001: w_mask_to_axi4_reg <= 8'b0000_0110;
                    3'b010: w_mask_to_axi4_reg <= 8'b0000_1100;
                    3'b011: w_mask_to_axi4_reg <= 8'b0001_1000;
                    3'b100: w_mask_to_axi4_reg <= 8'b0011_0000;
                    3'b101: w_mask_to_axi4_reg <= 8'b0110_0000;
                    3'b110: w_mask_to_axi4_reg <= 8'b1100_0000;
                    3'b111: w_mask_to_axi4_reg <= 8'b1000_0000;
                endcase
                2'b10: case (rw_mem_addr[2:0])
                    3'b000: w_mask_to_axi4_reg <= 8'b0000_1111;
                    3'b001: w_mask_to_axi4_reg <= 8'b0001_1110;
                    3'b010: w_mask_to_axi4_reg <= 8'b0011_1100;
                    3'b011: w_mask_to_axi4_reg <= 8'b0111_1000;
                    3'b100: w_mask_to_axi4_reg <= 8'b1111_0000;
                    3'b101: w_mask_to_axi4_reg <= 8'b1110_0000;
                    3'b110: w_mask_to_axi4_reg <= 8'b1100_0000;
                    3'b111: w_mask_to_axi4_reg <= 8'b1000_0000;
                endcase
                2'b11: case (rw_mem_addr[2:0])
                    3'b000: w_mask_to_axi4_reg <= 8'b1111_1111;
                    3'b001: w_mask_to_axi4_reg <= 8'b1111_1110;
                    3'b010: w_mask_to_axi4_reg <= 8'b1111_1100;
                    3'b011: w_mask_to_axi4_reg <= 8'b1111_1000;
                    3'b100: w_mask_to_axi4_reg <= 8'b1111_0000;
                    3'b101: w_mask_to_axi4_reg <= 8'b1110_0000;
                    3'b110: w_mask_to_axi4_reg <= 8'b1100_0000;
                    3'b111: w_mask_to_axi4_reg <= 8'b1000_0000;
                endcase
            endcase
        end
        else if(nxt_state==3'd6) begin
            case(rw_mem_bytes[1:0])
                2'b00: w_mask_to_axi4_reg <= 8'b0000_0000;
                2'b01: case (rw_mem_addr[2:0])
                    3'b111: w_mask_to_axi4_reg <= 8'b0000_00001;
                    default: w_mask_to_axi4_reg <= 8'b0000_0000;
                endcase
                2'b10: case (rw_mem_addr[2:0])
                    3'b101: w_mask_to_axi4_reg <= 8'b0000_0001;
                    3'b110: w_mask_to_axi4_reg <= 8'b0000_0011;
                    3'b111: w_mask_to_axi4_reg <= 8'b0000_0111;
                    default: w_mask_to_axi4_reg <= 8'b0000_0000;
                endcase
                2'b11: case (rw_mem_addr[2:0])
                    3'b000: w_mask_to_axi4_reg <= 8'b0000_0000;
                    3'b001: w_mask_to_axi4_reg <= 8'b0000_0001;
                    3'b010: w_mask_to_axi4_reg <= 8'b0000_0011;
                    3'b011: w_mask_to_axi4_reg <= 8'b0000_0111;
                    3'b100: w_mask_to_axi4_reg <= 8'b0000_1111;
                    3'b101: w_mask_to_axi4_reg <= 8'b0001_1111;
                    3'b110: w_mask_to_axi4_reg <= 8'b0011_1111;
                    3'b111: w_mask_to_axi4_reg <= 8'b0111_1111;
                endcase
            endcase
        end
    end

endmodule
